package com.blr.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.security.SpringSessionBackedSessionRegistry;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final FindByIndexNameSessionRepository findByIndexNameSessionRepository;

    @Autowired
    public  SecurityConfig(FindByIndexNameSessionRepository findByIndexNameSessionRepository){
        this.findByIndexNameSessionRepository = findByIndexNameSessionRepository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .logout()
                .and()
                .csrf().disable()
                .sessionManagement()//开启会话管理
                .maximumSessions(1)//允许会话最大并发只能一个客户端
                //.expiredUrl("/login");//传统架的处理方案 当用户被挤下线之后跳转的路径
                .expiredSessionStrategy((event)->{ //前后端分离的处理方案 当用户被挤下线之后的处理方案
                    HttpServletResponse response = event.getResponse();
                    Map<String,Object> result = new HashMap<>();
                    result.put("status",200);
                    result.put("msg","当前会话已失效，请重新登录");
                    String s = new ObjectMapper().writeValueAsString(result); //java对象转换成json
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().println(s);
                    response.flushBuffer();
                })
                .sessionRegistry(sessionRegistry()) //通过将session交给谁管理
                .maxSessionsPreventsLogin(true);//一旦登录 禁止再次登录
    }

    @Bean
    public SpringSessionBackedSessionRegistry sessionRegistry(){
        return new SpringSessionBackedSessionRegistry(findByIndexNameSessionRepository);
    }

    //监听会话的创建与销毁 现在版本可以不加
    //@Bean
    //public HttpSessionEventPublisher httpSessionEventPublisher(){
        //return new HttpSessionEventPublisher();
    //}
}
